"""我们为成员相关的验证定义了一个依赖函数."""
import hashlib
from typing_extensions import Annotated

from fastapi import Depends, Form, Path, Request, status
from fastapi.responses import RedirectResponse

from core.exception import AlertException
from core.formclass import RegisterMemberForm, UpdateMemberForm
from core.models import Member
from lib.common import is_none_datetime
from lib.dependency.auth import get_login_member
from lib.pbkdf2 import create_hash, validate_password
from service.member_service import MemberService, ValidateMember


def validate_policy_agree(request: Request):
    """条款协议的检查"""
    if (not request.session.get("ss_agree", None)
            or not request.session.get("ss_agree2", None)):
        raise AlertException("您同意会员条款.", 400, url="/bbs/register")


def validate_register_data(
    validate: Annotated[ValidateMember, Depends()],
    data: Annotated[RegisterMemberForm, Depends()],
):
    """加入时验证成员信息."""
    validate.valid_id(data.mb_id)
    validate.valid_name(data.mb_name)
    validate.valid_nickname(data.mb_nick)
    validate.valid_email(data.mb_email)
    validate.valid_recommend(data.mb_recommend, data.mb_id)

    return data


def validate_update_data(
    validate: Annotated[ValidateMember, Depends()],
    member: Annotated[Member, Depends(get_login_member)],
    data: Annotated[UpdateMemberForm, Depends()],
):
    """验证固定的成员信息."""
    # 昵称更改验证
    if member.mb_nick != data.mb_nick:
        validate.valid_nickname(data.mb_nick)
        validate.valid_nickname_change_date(member.mb_nick_date)
    else:
        del data.mb_nick_date

    # 电子邮件更改验证
    if member.mb_email != data.mb_email:
        validate.valid_email(data.mb_email)

    # 成员信息公共变更验证
    if data.mb_open != member.mb_open:
        validate.valid_open_change_date(member.mb_open_date)
    else:
        del data.mb_open_date

    return data


def validate_leave_member(
    request: Request,
    member: Annotated[Member, Depends(get_login_member)],
    mb_password: str = Form(...),
):
    """成员离开时验证成员信息."""
    if request.state.is_super_admin:
        raise AlertException("高层管理人员不能离开.", 400)
    if not validate_password(mb_password, member.mb_password):
        raise AlertException("密码不匹配.", 400)


def redirect_if_logged_in(request: Request) -> None:
    """如果您已登录，请重定向到主页."""
    member = request.state.login_member
    if member:
        return RedirectResponse("/", status_code=status.HTTP_303_SEE_OTHER)
    return None


def validate_password_reset(
    mb_password: str = Form(..., min_length=4, max_length=20),
    mb_password_confirm: str = Form(..., min_length=4, max_length=20)
) -> str:
    """重置密码时，它会检查密码是否匹配."""
    if mb_password != mb_password_confirm:
        raise AlertException("密码不匹配.", 400)

    return create_hash(mb_password)


def validate_certify_email_member(
    member_service: Annotated[MemberService, Depends()],
    mb_id: str = Path(...),
    key: str = Path(...)
):
    """
    进行身份验证电子邮件更改时验证成员信息.
    """
    member = member_service.fetch_member_by_id(mb_id)

    if not is_none_datetime(member.mb_email_certify):
        raise AlertException("这是一个已经完成邮件身份验证的成员.", 409)

    check_key = hashlib.md5(f"{member.mb_ip}{member.mb_datetime}".encode()).hexdigest()
    if not key or key != check_key:
        raise AlertException("请使用正确的方式.", 400)

    return member


def logout_only_view(request: Request):
    """检查页面是否仅在注销时才可访问的函数"""
    session_mb_id = request.session.get("ss_mb_id", "")
    if session_mb_id:
        raise AlertException("仅当您已注销时.", 403, url="/")